﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel;
using System.Text;
//librerias especiales para la BD
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Data.SqlTypes;

namespace CityGames
{
    public class CADAlquiler
    {
        static private string cadConexion = System.Configuration.ConfigurationManager.ConnectionStrings["CityGames.Properties.Settings.BDCityGamesConnectionString"].ConnectionString;

        /*************************************************Funciones Ruben ***********************************************/

        /// <summary>
        /// Funcion que inserta un alquiler o venta temporalmente en la BD para luego añadirlo a la lista de la compra.
        /// </summary>
        /// <param name="codigo">
        /// El codigo de la copia del juego.</param>
        /// <param name="nombreJuego">
        /// El nombre de la copia del juego.</param>
        /// <param name="plataformaJuego">
        /// La plataforma del juego.</param>
        /// <param name="precio">
        /// El precio que tiene el juego.</param>
        /// <param name="tipo">
        /// El tipo del juego (nuevo, segunda mano o alquiler).</param>
        /// <returns>
        /// Devuelve un booleano que indica si se ha insertado correctamente el juego</returns>
        public bool InsertarAlquiler(int codigo, string nombreJuego, string plataformaJuego, decimal precio, string tipo)
        {
            bool resultado = false;

            SqlConnection conexion = null;
            SqlTransaction tr = null;
            SqlCommand comandoSql = null;
            string insert = "";
            SqlParameter param = new SqlParameter("@precio", precio);

            try
            {
                insert += "INSERT INTO AlquileresVirtual (Codigo, NombreJuego, Plataforma, Precio, Tipo)";
                insert += "VALUES        (" + codigo + ", '" + nombreJuego + "', '" + plataformaJuego + "', @precio, '" + tipo + "')";

                conexion = new SqlConnection(cadConexion);
                conexion.Open();

                tr = conexion.BeginTransaction();

                comandoSql = new SqlCommand(insert, conexion);
                comandoSql.Parameters.Add(param);
                comandoSql.Transaction = tr;
                comandoSql.ExecuteNonQuery();    

                tr.Commit();
                resultado = true;
            }
            catch (Exception ex)
            {
                tr.Rollback();
                throw ex;
            }
            finally
            {
                if (conexion != null)
                    conexion.Close();
            }

            return resultado;
        }

        /// <summary>
        /// Funcion que devuelve el numero de juegos almacenados en la tabla AlquileresVirtual de la Base de Datos.
        /// </summary>        
        /// <returns>
        /// Devuelve el numero de juegos</returns>
        public int NumeroAlquileres()
        {
            int resultado = 0;
            string select = "";
            SqlConnection conexion = null;

            try
            {
                select += "SELECT COUNT(*) FROM AlquileresVirtual";
                conexion = new SqlConnection(cadConexion);
                conexion.Open();

                SqlCommand comandoSql = new SqlCommand(select, conexion);
                SqlDataReader dr = comandoSql.ExecuteReader();

                if (dr.Read())
                    resultado = int.Parse(dr[0].ToString());
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (conexion != null)
                    conexion.Close();
            }

            return resultado;
        }

        /// <summary>
        /// Obtener los juegos almacenados en la tabla AlquileresVirtual de forma paginada
        /// </summary>        
        /// <param name="desde">
        /// Entero que indica desde que número de fila se desea mostrar</param>
        /// <param name="hasta">
        /// Entero que indica hasta que número de fila se desea mostrar</param>
        /// <returns>
        /// Un dataset con los juegos
        /// </returns>
        public DataSet Alquileres(int desde, int hasta)
        {
            string select = "";
            DataSet resultado = new DataSet();

            try
            {
                select += "SELECT      Codigo, Nombre, Plataforma, Tipo, Precio ";
                select += "FROM         (SELECT    Codigo, NombreJuego as Nombre, Plataforma, Precio, Tipo, ROW_NUMBER() OVER (ORDER BY Codigo ASC) AS ROW  ";
                select += "              FROM          AlquileresVirtual) AS AlquileresNumerdados ";
                select += "WHERE (ROW >" + desde.ToString() + ") AND (ROW <=" + hasta.ToString() + ") ";

                SqlConnection conexion = new SqlConnection(cadConexion);
                SqlDataAdapter da = new SqlDataAdapter(select, conexion);
                da.Fill(resultado, "Alquileres");
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return resultado;
        }

        /// <summary>
        /// Obtener los juegos almacenados en la tabla AlquileresVirtual
        /// </summary>                
        /// <returns>
        /// Un dataset con los juegos
        /// </returns>
        public DataSet AlquileresSinPaginar()
        {
            string select = "";
            DataSet resultado = new DataSet();

            try
            {
                select += "SELECT      Codigo, Nombre, Plataforma, Tipo, Precio ";
                select += "FROM         (SELECT    Codigo, NombreJuego as Nombre, Plataforma, Precio, Tipo, ROW_NUMBER() OVER (ORDER BY Codigo ASC) AS ROW  ";
                select += "              FROM          AlquileresVirtual) AS AlquileresNumerdados ";

                SqlConnection conexion = new SqlConnection(cadConexion);
                SqlDataAdapter da = new SqlDataAdapter(select, conexion);
                da.Fill(resultado, "AlquileresSinPaginar");
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return resultado;
        }

        /// <summary>
        /// Vaciar la tabla AlquileresVirtual
        /// </summary>        
        public void VaciarTabla()
        {
            string select = "";
            SqlConnection conexion = null;
            SqlTransaction tr = null;
            SqlCommand comandoSql = null;

            try
            {
                select += "DELETE FROM AlquileresVirtual";

                conexion = new SqlConnection(cadConexion);
                conexion.Open();

                tr = conexion.BeginTransaction();

                comandoSql = new SqlCommand(select, conexion);
                comandoSql.Transaction = tr;
                comandoSql.ExecuteNonQuery();

                tr.Commit();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (conexion != null)
                    conexion.Close();
            }
        }

        /// <summary>
        /// Quita un juego de la tabla AlquileresVirtual
        /// </summary>        
        /// <param name="codigo">
        /// El codigo del juego que se desea borrar</param>
        public void QuitarAlquilerBD(int codigo)
        {
            string select = "";
            SqlConnection conexion = null;
            SqlTransaction tr = null;
            SqlCommand comandoSql = null;

            try
            {
                select += "DELETE FROM AlquileresVirtual ";
                select += "WHERE Codigo = " + codigo;

                conexion = new SqlConnection(cadConexion);
                conexion.Open();

                tr = conexion.BeginTransaction();

                comandoSql = new SqlCommand(select, conexion);
                comandoSql.Transaction = tr;
                comandoSql.ExecuteNonQuery();

                tr.Commit();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (conexion != null)
                    conexion.Close();
            }
        }

        /// <summary>
        /// Obtener los juegos almacenados en la tabla AlquileresVirtual con su descuento correspondiente si lo tuvieran
        /// </summary>        
        /// <returns>
        /// Un dataset con los juegos
        /// </returns>
        public DataSet AlquileresConPromociones()
        {
            string select = "";
            DataSet resultado = new DataSet();

            try
            {
                select += "SELECT        Codigo, Nombre, Plataforma, Precio, Tipo, Promocion, DescuentoPorcentaje, DescuentoEuros, '' AS Total ";
                select += "FROM            (SELECT        AV.Codigo, AV.NombreJuego AS Nombre, AV.Plataforma, AV.Precio, AV.Tipo, '2X1' AS Promocion, '0' AS DescuentoPorcentaje,  ";
                select += "                                    '0' AS DescuentoEuros ";
                select += "                          FROM            AlquileresVirtual AS AV INNER JOIN ";
                select += "                                                    JuegosPromociones AS JP ON AV.NombreJuego = JP.Nombre AND AV.Plataforma = JP.Plataforma INNER JOIN ";
                select += "                                                    Promocion AS P ON JP.Codigo = P.CodigoPromocion ";
                select += "                          WHERE        (P.TipoDescuento = 3) AND (GETDATE() BETWEEN P.FechaInicio AND P.FechaFin) ";
                select += "                          GROUP BY AV.Codigo, AV.NombreJuego, AV.Plataforma, AV.Precio, AV.Tipo ";
                select += "                          UNION ALL ";
                select += "                          SELECT        AV.Codigo, AV.NombreJuego AS Nombre, AV.Plataforma, AV.Precio, AV.Tipo, 'Descuento en €' AS Promocion, '0' AS DescuentoPorcentaje,  ";
                select += "                                                   MAX(P.CantidadDescuento) AS DescuentoEuros ";
                select += "                          FROM            AlquileresVirtual AS AV INNER JOIN ";
                select += "                                                   JuegosPromociones AS JP ON AV.NombreJuego = JP.Nombre AND AV.Plataforma = JP.Plataforma INNER JOIN ";
                select += "                                                   Promocion AS P ON JP.Codigo = P.CodigoPromocion ";
                select += "                          WHERE        (P.TipoDescuento = 1) AND (GETDATE() BETWEEN P.FechaInicio AND P.FechaFin) AND (AV.Codigo NOT IN ";
                select += "                                                       (SELECT        AV.Codigo ";
                select += "                                                         FROM            AlquileresVirtual AS AV INNER JOIN ";
                select += "                                                                                   JuegosPromociones AS JP ON AV.NombreJuego = JP.Nombre AND AV.Plataforma = JP.Plataforma INNER JOIN ";
                select += "                                                                                   Promocion AS P ON JP.Codigo = P.CodigoPromocion ";
                select += "                                                         WHERE        (P.TipoDescuento = 3) AND (GETDATE() BETWEEN P.FechaInicio AND P.FechaFin))) ";
                select += "                          GROUP BY AV.Codigo, AV.NombreJuego, AV.Plataforma, AV.Precio, AV.Tipo ";
                select += "                          UNION ALL ";
                select += "                          SELECT        AV.Codigo, AV.NombreJuego AS Nombre, AV.Plataforma, AV.Precio, AV.Tipo, 'Descuento en %' AS Promocion, MAX(P.CantidadDescuento)  ";
                select += "                                                   AS DescuentoPorcentaje, '0' AS DescuentoEuros ";
                select += "                          FROM            AlquileresVirtual AS AV INNER JOIN ";
                select += "                                                   JuegosPromociones AS JP ON AV.NombreJuego = JP.Nombre AND AV.Plataforma = JP.Plataforma INNER JOIN ";
                select += "                                                   Promocion AS P ON JP.Codigo = P.CodigoPromocion ";
                select += "                          WHERE        (P.TipoDescuento = 2) AND (GETDATE() BETWEEN P.FechaInicio AND P.FechaFin) AND (AV.Codigo NOT IN ";
                select += "                                                       (SELECT        AV.Codigo ";
                select += "                                                         FROM            AlquileresVirtual AS AV INNER JOIN ";
                select += "                                                                                   JuegosPromociones AS JP ON AV.NombreJuego = JP.Nombre AND AV.Plataforma = JP.Plataforma INNER JOIN ";
                select += "                                                                                   Promocion AS P ON JP.Codigo = P.CodigoPromocion ";
                select += "                                                         WHERE        (P.TipoDescuento = 3 OR ";
                select += "                                                                                   P.TipoDescuento = 1) AND (GETDATE() BETWEEN P.FechaInicio AND P.FechaFin))) ";
                select += "                          GROUP BY AV.Codigo, AV.NombreJuego, AV.Plataforma, AV.Precio, AV.Tipo ";
                select += "                          UNION ALL ";
                select += "                          SELECT        Codigo, NombreJuego AS Nombre, Plataforma, Precio, Tipo, 'Ninguna' AS Promocion, '0' AS DescuentoPorcentaje, '0' AS DescuentoEuros ";
                select += "                          FROM            AlquileresVirtual AS AV ";
                select += "                          WHERE        (Codigo NOT IN ";
                select += "                                                       (SELECT        AV.Codigo ";
                select += "                                                         FROM            AlquileresVirtual AS AV INNER JOIN ";
                select += "                                                                                   JuegosPromociones AS JP ON AV.NombreJuego = JP.Nombre AND AV.Plataforma = JP.Plataforma INNER JOIN ";
                select += "                                                                                   Promocion AS P ON JP.Codigo = P.CodigoPromocion ";
                select += "                                                         WHERE        (P.TipoDescuento = 1 OR ";
                select += "                                                                                   P.TipoDescuento = 2 OR ";
                select += "                                                                                   P.TipoDescuento = 3) AND (GETDATE() BETWEEN P.FechaInicio AND P.FechaFin)))) AS TablaSeleccion ";

                SqlConnection conexion = new SqlConnection(cadConexion);
                SqlDataAdapter da = new SqlDataAdapter(select, conexion);
                da.Fill(resultado, "AlquileresConPromociones");
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return resultado;
        }

        /// <summary>
        /// Funcion que devuelve el numero de juegos
        /// </summary>        
        /// <returns>
        /// El numero de juegos
        /// </returns>
        public int NumeroAlquileresConPromociones()
        {
            int resultado = 0;
            string select = "";
            SqlConnection conexion = null;

            try
            {
                select += "SELECT count(*) ";
                select += "FROM (SELECT        Codigo, Nombre, Plataforma, Precio, Tipo, Promocion, DescuentoPorcentaje, DescuentoEuros, '' AS Total ";
                select += "FROM            (SELECT        AV.Codigo, AV.NombreJuego AS Nombre, AV.Plataforma, AV.Precio, AV.Tipo, '2X1' AS Promocion, '0' AS DescuentoPorcentaje,  ";
                select += "                                    '0' AS DescuentoEuros ";
                select += "                          FROM            AlquileresVirtual AS AV INNER JOIN ";
                select += "                                                    JuegosPromociones AS JP ON AV.NombreJuego = JP.Nombre AND AV.Plataforma = JP.Plataforma INNER JOIN ";
                select += "                                                    Promocion AS P ON JP.Codigo = P.CodigoPromocion ";
                select += "                          WHERE        (P.TipoDescuento = 3) AND (GETDATE() BETWEEN P.FechaInicio AND P.FechaFin) ";
                select += "                          GROUP BY AV.Codigo, AV.NombreJuego, AV.Plataforma, AV.Precio, AV.Tipo ";
                select += "                          UNION ALL ";
                select += "                          SELECT        AV.Codigo, AV.NombreJuego AS Nombre, AV.Plataforma, AV.Precio, AV.Tipo, 'Descuento en €' AS Promocion, '0' AS DescuentoPorcentaje,  ";
                select += "                                                   MAX(P.CantidadDescuento) AS DescuentoEuros ";
                select += "                          FROM            AlquileresVirtual AS AV INNER JOIN ";
                select += "                                                   JuegosPromociones AS JP ON AV.NombreJuego = JP.Nombre AND AV.Plataforma = JP.Plataforma INNER JOIN ";
                select += "                                                   Promocion AS P ON JP.Codigo = P.CodigoPromocion ";
                select += "                          WHERE        (P.TipoDescuento = 1) AND (GETDATE() BETWEEN P.FechaInicio AND P.FechaFin) AND (AV.Codigo NOT IN ";
                select += "                                                       (SELECT        AV.Codigo ";
                select += "                                                         FROM            AlquileresVirtual AS AV INNER JOIN ";
                select += "                                                                                   JuegosPromociones AS JP ON AV.NombreJuego = JP.Nombre AND AV.Plataforma = JP.Plataforma INNER JOIN ";
                select += "                                                                                   Promocion AS P ON JP.Codigo = P.CodigoPromocion ";
                select += "                                                         WHERE        (P.TipoDescuento = 3) AND (GETDATE() BETWEEN P.FechaInicio AND P.FechaFin))) ";
                select += "                          GROUP BY AV.Codigo, AV.NombreJuego, AV.Plataforma, AV.Precio, AV.Tipo ";
                select += "                          UNION ALL ";
                select += "                          SELECT        AV.Codigo, AV.NombreJuego AS Nombre, AV.Plataforma, AV.Precio, AV.Tipo, 'Descuento en %' AS Promocion, MAX(P.CantidadDescuento)  ";
                select += "                                                   AS DescuentoPorcentaje, '0' AS DescuentoEuros ";
                select += "                          FROM            AlquileresVirtual AS AV INNER JOIN ";
                select += "                                                   JuegosPromociones AS JP ON AV.NombreJuego = JP.Nombre AND AV.Plataforma = JP.Plataforma INNER JOIN ";
                select += "                                                   Promocion AS P ON JP.Codigo = P.CodigoPromocion ";
                select += "                          WHERE        (P.TipoDescuento = 2) AND (GETDATE() BETWEEN P.FechaInicio AND P.FechaFin) AND (AV.Codigo NOT IN ";
                select += "                                                       (SELECT        AV.Codigo ";
                select += "                                                         FROM            AlquileresVirtual AS AV INNER JOIN ";
                select += "                                                                                   JuegosPromociones AS JP ON AV.NombreJuego = JP.Nombre AND AV.Plataforma = JP.Plataforma INNER JOIN ";
                select += "                                                                                   Promocion AS P ON JP.Codigo = P.CodigoPromocion ";
                select += "                                                         WHERE        (P.TipoDescuento = 3 OR ";
                select += "                                                                                   P.TipoDescuento = 1) AND (GETDATE() BETWEEN P.FechaInicio AND P.FechaFin))) ";
                select += "                          GROUP BY AV.Codigo, AV.NombreJuego, AV.Plataforma, AV.Precio, AV.Tipo ";
                select += "                          UNION ALL ";
                select += "                          SELECT        Codigo, NombreJuego AS Nombre, Plataforma, Precio, Tipo, 'Ninguna' AS Promocion, '0' AS DescuentoPorcentaje, '0' AS DescuentoEuros ";
                select += "                          FROM            AlquileresVirtual AS AV ";
                select += "                          WHERE        (Codigo NOT IN ";
                select += "                                                       (SELECT        AV.Codigo ";
                select += "                                                         FROM            AlquileresVirtual AS AV INNER JOIN ";
                select += "                                                                                   JuegosPromociones AS JP ON AV.NombreJuego = JP.Nombre AND AV.Plataforma = JP.Plataforma INNER JOIN ";
                select += "                                                                                   Promocion AS P ON JP.Codigo = P.CodigoPromocion ";
                select += "                                                         WHERE        (P.TipoDescuento = 1 OR ";
                select += "                                                                                   P.TipoDescuento = 2 OR ";
                select += "                                                                                   P.TipoDescuento = 3) AND (GETDATE() BETWEEN P.FechaInicio AND P.FechaFin)))) AS TablaSeleccion ) ";

                conexion = new SqlConnection(cadConexion);
                conexion.Open();

                SqlCommand comandoSql = new SqlCommand(select, conexion);
                SqlDataReader dr = comandoSql.ExecuteReader();

                if (dr.Read())
                    resultado = int.Parse(dr[0].ToString());
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (conexion != null)
                    conexion.Close();
            }

            return resultado;
        }

        /*************************************************Fin Funciones Ruben ***********************************************/

    }
}
